function deepEqual(a, b, map = new WeakMap()) {
  if (a === b) return true;

  if (
    typeof a !== "object" ||
    a === null ||
    typeof b !== "object" ||
    b === null
  ) {
    return false;
  }

  if (map.has(a)) return map.get(a) === b; // 防止循环引用
  map.set(a, b);

  const keysA = Object.keys(a);
  const keysB = Object.keys(b);

  if (keysA.length !== keysB.length) return false;

  for (let key of keysA) {
    if (!keysB.includes(key) || !deepEqual(a[key], b[key], map)) return false;
  }

  return true;
}
